from django.db import transaction
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer

from celery_tasks.static_file.tasks import get_static_sku_detail_html
from goods.models import SKU, SKUSpecification, GoodsCategory, SPUSpecification, SpecificationOption


class SpecificationOptionSerializers(ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = '__all__'

class SPUSpecificationSerializers(ModelSerializer):
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    options = SpecificationOptionSerializers(many=True)
    class Meta:
        model = SPUSpecification
        fields = '__all__'


class GoodsCategorySerializers(ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = '__all__'


class SKUSpecificationSerializers(ModelSerializer):

    class Meta:
        model = SKUSpecification
        fields = ('spec_id','option_id')


class SKUSerializers(ModelSerializer):
    # 关联嵌套序列化
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    category = serializers.StringRelatedField(read_only=True)
    category_id = serializers.IntegerField()
    specs = SKUSpecificationSerializers(many=True,read_only=True)


    class Meta:
        model = SKU
        fields = '__all__'
        read_only_fields = ('spu','category')

    def create(self, validated_data):
        specs = self.context['request'].data.get('specs')
        # 开启事务
        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                # sku表
                sku = SKU.objects.create(**validated_data)
                # skuspecs表
                for spec in specs:
                    SKUSpecification.objects.create(sku=sku,spec_id=spec['spec_id'],option_id=spec['option_id'])
            except:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError('数据库保存失败')
            else:
                # 成功提交
                transaction.savepoint_commit(save_point)
                # 异步生成商品静态页面
                get_static_sku_detail_html.delay(sku.id)
                return sku

    def update(self, instance, validated_data):
        specs = self.context['request'].data.get('specs')

        # 开启事务
        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                # sku表
                SKU.objects.filter(id=instance.id).update(**validated_data)
                # skuspecs表
                num = 0
                for spec in specs:
                    SKUSpecification.objects.filter(sku=instance).update(**spec)
            except:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError('数据库保存失败')
            else:
                # 成功提交
                transaction.savepoint_commit(save_point)
                # 异步生成商品静态页面
                get_static_sku_detail_html.delay(instance.id)

                return instance


